#include "svglineelement.h"
#include "colortransformer.h"
#include <QRegion>
#include "svghelper.h"
#include "../pointitemcontainer.h"

SvgLineElement::SvgLineElement(SvgNode *parent)
    :SvgNodeElement(parent),
	m_p1(QPointF(0,0)),
	m_p2(QPointF(0, 0))
{
    m_pointItemContainer = new PointItemContainer(this);
    m_pointItemContainer->setDelegate(this);
    this->setMouseMode(MouseMode_DRAW);
    m_pointItemContainer->setPointItemMode(PointItemMode_EDIT);
}

void SvgLineElement::paint(QPainter *painter,
                   const QStyleOptionGraphicsItem *option,
                   QWidget *widget){

    if(m_pointItemContainer->getPointItemMode() == PointItemMode_EDIT)
    {
        if(option->state & QStyle::State_Selected)
        {
            m_pointItemContainer->showPointItems(true);
        }
        else
        {
            if(!m_pointItemContainer->isPointItemHaveSelected())
            {
                m_pointItemContainer->showPointItems(false);
            }
        }
    }
    SvgNodeElement::paint(painter,option,widget);

    if(m_points.count()>1)
    {
        painter->drawLine(m_p1,m_p2);
    }
}
void SvgLineElement::cloneImpl(SvgNode *node){
	SvgNodeElement::cloneImpl(node);
	SvgLineElement *p = qobject_cast<SvgLineElement*>(node);
	if (p)
	{
		p->m_p1 = m_p1;
		p->m_p2 = m_p2;
	}

}
void SvgLineElement::updateShape() {
	m_shape = QPainterPath();
	
	m_shape.addRegion(regionFrom2Points(m_p1, m_p2));
}


void SvgLineElement::fromXmlImpl(const QDomElement &xml) {

	qreal x1, y1, x2, y2;
	x1 = y1 = x2 = y2 = 0;
	if (xml.hasAttribute("x1"))
		x1 = xml.attribute("x1").toDouble();

	if (xml.hasAttribute("y1"))
		y1 = xml.attribute("y1").toDouble();

	if (xml.hasAttribute("x2"))
		x2 = xml.attribute("x2").toDouble();

	if (xml.hasAttribute("y2"))
		y2 = xml.attribute("y2").toDouble();

	m_p1 = QPointF(x1, y1);
	m_p2 = QPointF(x2, y2);
    m_points.append(m_p1);
    m_points.append(m_p2);

    ILink::fromXml(xml);

}
QDomElement SvgLineElement::toXmlImpl(QDomElement &parent) const{
	QDomElement curr = parent.ownerDocument().createElement("line");

	QPointF offset = fixedOriginPoint() - m_frame.topLeft() - QPointF(m_strokeWidth / 2., m_strokeWidth / 2.);
	curr.setAttribute("x1", QString("%1").arg(m_p1.x() + this->pos().x() + offset.x()));
	curr.setAttribute("y1", QString("%1").arg(m_p1.y() + this->pos().y() + offset.y()));
	curr.setAttribute("x2", QString("%1").arg(m_p2.x() + this->pos().x() + offset.x()));
	curr.setAttribute("y2", QString("%1").arg(m_p2.y() + this->pos().y() + offset.y()));

    ILink::toXml(curr);
	return curr;
}
void SvgLineElement::updateFrame(){
	//reset frame	
	qreal minx = m_p1.x() < m_p2.x() ? m_p1.x() : m_p2.x();
	qreal miny = m_p1.y() < m_p2.y() ? m_p1.y() : m_p2.y();
	m_frame = QRectF(minx - m_strokeWidth / 2.f , miny - m_strokeWidth / 2.f -0 , abs(m_p1.x() - m_p2.x()) + m_strokeWidth , abs(m_p1.y() - m_p2.y()) + m_strokeWidth + 0);
	frameSizeCheck();
}

void SvgLineElement::onResize(QRectF rect){

	QRectF rectNew = rect;
	//fix
	rectNew = QRectF(rectNew.x() + m_strokeWidth / 2.f, rectNew.y() + m_strokeWidth / 2.f, rectNew.width() - m_strokeWidth, rectNew.height() - m_strokeWidth);
	QRectF rectOld = QRectF(m_frame.x() + m_strokeWidth / 2.f, m_frame.y() + m_strokeWidth / 2.f, m_frame.width() - m_strokeWidth, m_frame.height() - m_strokeWidth);

	QPointF fixedPoint;
	if (this->resizeFixedPoint(rectNew, rectOld, fixedPoint))
	{
		qreal xScale = rectNew.width() / rectOld.width();
		qreal yScale = 1;// rectNew.height() / rectOld.height();

		m_p1 = QPointF(fixedPoint.x() + (m_p1.x() - fixedPoint.x())*xScale, fixedPoint.y() + (m_p1.y() - fixedPoint.y()) *yScale);
		m_p2 = QPointF(fixedPoint.x() + (m_p2.x() - fixedPoint.x())*xScale, fixedPoint.y() + (m_p2.y() - fixedPoint.y()) *yScale);
		updateFrame();
		updateShape();
	}
	SvgNode::onResize(rect);
}
QList<QPointF> SvgLineElement::alignPoints(QPointF &center){
	QList<QPointF> list;
	QPointF offset = fixedOriginPoint() - m_frame.topLeft() - QPointF(m_strokeWidth / 2., m_strokeWidth / 2.);
	list.append(m_p1 + offset);
	list.append(m_p2 + offset);
	
	center = (m_p1 + m_p2) / 2. + offset;
	return list;
}
//////////add by sam 20140806
void SvgLineElement::appendPoint(const QPointF &p)
{
    if(myMode == MouseMode_DRAW)
    {
        QPointF newpos = this->mapFromScene(p);
        m_points.append(newpos);


        if (m_points.count() == 1)
            m_p1 = newpos;
        else
            m_p2 = newpos;

        if(m_points.count()>1)
        {
            updateFrame();
            updateShape();
        }

        m_pointItemContainer->setLineColor(m_stroke);
        m_pointItemContainer->setLineWidth(m_strokeWidth);
    }
}
void SvgLineElement::onPointPosChanged(int idx, QPointF newPoint){

    QPointF tranPoint = this->mapFromScene(newPoint);
    m_points.replace(idx, tranPoint);

    if (idx == 0)
    {
        if (!m_fromEnd.isNull())
        {
            m_fromEnd.node->removeConnectionByLine(this, true);
            m_fromEnd.node = NULL;
        }

        tryConnecte(topParent(), newPoint,true);
        m_p1.setX(tranPoint.x());
        m_p1.setY(tranPoint.y());
    }
    if (idx == m_points.count()-1)
    {
        if (!m_toEnd.isNull())
        {
            m_toEnd.node->removeConnectionByLine(this, false);
            m_toEnd.node = NULL;
        }

        tryConnecte(topParent(), newPoint,false);
        m_p2.setX(tranPoint.x());
        m_p2.setY(tranPoint.y());
    }



    updateFrame();
    updateShape();
}
void SvgLineElement::replaceWithScenePoint(bool isStart, QPointF newPoint) {

    if (isStart)
        m_points.replace(0, this->mapFromScene(newPoint));
    else
        m_points.replace(m_points.count() - 1, this->mapFromScene(newPoint));

    updateFrame();
    updateShape();

    //this->update(m_frame);
    //qApp->processEvents();
}
bool SvgLineElement::tiePointCheckDelegate(QPointF curr, QPointF *res){
    SvgNode *top = topParent();
    return top->tiePointCheck(curr, res);
}
bool SvgLineElement::twoEndpointsLinked()
{
    if(m_toEnd.isNull())
    {
        return false;
    }
    return true;
}
void SvgLineElement::setMouseMovePos(QPointF pos)
{
    m_pointItemContainer->mMousePos = pos;
    m_pointItemContainer->update(QRectF(0,0,0,0));
}
void SvgLineElement::setDrawLineShow(bool vis)
{
    if(vis)
    {
        m_pointItemContainer->setPointItemMode(PointItemMode_DRAWLINE);
    }
    else
    {
        m_pointItemContainer->setPointItemMode(PointItemMode_EDIT);
    }
}
void SvgLineElement::updatePointItem()
{
    m_pointItemContainer->update(QRectF(0,0,0,0));
}
